package com.yoouce.patchmng.util;

import java.text.DateFormat;
import java.text.Format;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import org.apache.log4j.Logger;

/**
 * <日期工具类>
 * <功能详细描述>
 *
 * @author wangquan
 * @version [版本号, Dec 2, 2014]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public  class DateTools {
    private DateTools() {
    }

    private static final Logger LOG = Logger.getLogger(DateTools.class);

    public static final String yyyy_MM_dd = "yyyy-MM-dd";

    public static final String ddMMyyHHmmss = "ddMMyyHHmmss";

    public static final String yyyyMMddHHmmss = "yyyyMMddHHmmss";

    public static final String yyyyMMddHHmm = "yyyyMMddHHmm";

    public static final String yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";

    public static final String yyyy_MM_dd_HH_mm = "yyyy-MM-dd HH:mm";

    public static final String yyMMddHHmmss = "yyMMddHHmmss";

    public static final String yyyyMMdd = "yyyy年MM月dd日";

    public static final int MINUTE = Calendar.MINUTE;

    public static final int HOUR = Calendar.HOUR;

    public static final int DAY_OF_YEAR = Calendar.DAY_OF_YEAR;

    /**
     * 把日期字符串按格式字符串转换成Date类型
     *
     * @param fmtStr
     * @param dateStr
     * @return
     */
    public static Date paraseDate(String fmtStr, String dateStr) {
        DateFormat formatter = new SimpleDateFormat(fmtStr);
        try {
            return formatter.parse(dateStr);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 转换Date类型的格式
     *
     * @param fmtStr
     * @param date
     * @return
     */
    public static Date paraseDate(String fmtStr, Date date) {
        Format formatter = new SimpleDateFormat(fmtStr);
        String dateStr = formatter.format(date);
        return paraseDate(fmtStr, dateStr);
    }

    /**
     * 获取指定格式的日期
     *
     * @param formatStr
     * @return
     */
    public static String getDate(Date date, String formatStr) {
        String strDateTime;
        SimpleDateFormat format = new SimpleDateFormat(formatStr);
        strDateTime = format.format(date);
        return strDateTime;
    }

    /**
     * 获取当月的1月1号，用于初始化页面时间控件
     *
     * @return
     */
    public static String getCurMonthFirstDay(String format) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);

        return getDate(cal.getTime(), format);
    }

    public static String getDBCurMonthFirstDay(Date dbDate, String format) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(dbDate);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);

        return getDate(cal.getTime(), format);
    }

    /**
     * 获取当前时间的字符串形式
     *
     * @return
     */
    public static String getCurDay(String format) {
        return getDate(new Date(), format);
    }

    /**
     * 获取当前时间后几分钟的的失效时间字符串形式
     *
     * @param expiry 失效时间间隔
     * @param type   失效类型
     * @param format 字符串格式
     * @return
     */
    public static String getExpiryTime(int expiry, int type, String format) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.set(type, cal.get(type) + expiry);
        return getDate(cal.getTime(), format);
    }

    /**
     * 两个日期相减，返回相差的天数
     */
    public static long subtract(String startDate, String endDate) {
        SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM-dd");

        long day = 0L;
        try {
            Date date = myFormatter.parse(startDate);
            Date mydate = myFormatter.parse(endDate);
            day = (date.getTime() - mydate.getTime()) / 86400000L;
        } catch (ParseException e) {
            LOG.error(e);
        }
        return day;
    }

    /**
     * 二个日期包含天数endDate - startDate + 1
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static long interval(String startDate, String endDate) {
        SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM-dd");

        long day = 0L;
        try {
            Date date = myFormatter.parse(startDate);
            Date mydate = myFormatter.parse(endDate);
            day = (mydate.getTime() - date.getTime()) / 86400000L + 1;
        } catch (ParseException e) {
            LOG.error(e);
        }
        return day;
    }

    /**
     * 求某个日期所在月的最后一天
     *
     * @param date
     * @return
     */
    public static Date getLastDayOfMonth(Date date) {
        if (null == date) {
            return null;
        }

        Calendar calendar = Calendar.getInstance();

        calendar.clear();
        calendar.setTime(date);

        calendar.set(Calendar.DAY_OF_MONTH,
                calendar.getActualMaximum(calendar.DAY_OF_MONTH));

        return calendar.getTime();
    }

    /**
     * 求某年某月的最后一天
     *
     * @param year
     * @param month
     * @return
     */
    public static Date getLastDayOfMonth(int year, int month) {
        if (year < 1900) {
            return null;
        }

        if (month < 1 || month > 12) {
            return null;
        }

        Calendar calendar = Calendar.getInstance();

        calendar.clear();

        calendar.set(Calendar.YEAR, year);

        calendar.set(Calendar.MONTH, month - 1);

        calendar.set(Calendar.DAY_OF_MONTH,
                calendar.getActualMaximum(calendar.DAY_OF_MONTH));

        return calendar.getTime();
    }

    /**
     * 获取某个时间n年后的时间
     *
     * @param dbDate
     * @param format
     * @param n，表示n年后
     * @return
     */
    public static String getNyearsLater(Date dbDate, String format, int n) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(dbDate);
        cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) + n);
        return getDate(cal.getTime(), format);
    }

    /**
     * 返回给定日期的前一天
     *
     * @param date
     * @return
     */
    public static Date getPreviousDay(Date date) {

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_YEAR, cal.get(Calendar.DAY_OF_YEAR) - 1);
        return cal.getTime();
    }

    /**
     * 返回给定日期的下一天
     *
     * @param date
     * @return
     */
    public static Date getNextDay(Date date) {

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_YEAR, cal.get(Calendar.DAY_OF_YEAR) + 1);
        return cal.getTime();
    }

    /**
     * 获取日期字符串的第二天的字符串
     *
     * @param strDate
     * @return
     */
    public static String getNextDay(String strDate) {

        Date tmpDate = paraseDate(yyyy_MM_dd, strDate);
        Calendar cal = Calendar.getInstance();
        cal.setTime(tmpDate);
        cal.set(Calendar.DAY_OF_YEAR, cal.get(Calendar.DAY_OF_YEAR) + 1);

        return getDate(cal.getTime(), yyyy_MM_dd);
    }

    /**
     * 获取日期字符串的第interval天的字符串
     *
     * @param strDate
     * @param interval
     * @return
     */
    public static String getNextDay(String strDate, int interval) {

        Date tmpDate = paraseDate(yyyy_MM_dd, strDate);
        Calendar cal = Calendar.getInstance();
        cal.setTime(tmpDate);
        cal.set(Calendar.DAY_OF_YEAR, cal.get(Calendar.DAY_OF_YEAR) + interval);
        return getDate(cal.getTime(), yyyy_MM_dd);
    }

    /**
     * 返回给定日期的前一天
     *
     * @param date
     * @return
     */
    public static String getPreviousDay(String strDate) {

        Date tmpDate = paraseDate(yyyy_MM_dd, strDate);
        Calendar cal = Calendar.getInstance();
        cal.setTime(tmpDate);
        cal.set(Calendar.DAY_OF_YEAR, cal.get(Calendar.DAY_OF_YEAR) - 1);

        return getDate(cal.getTime(), yyyy_MM_dd);
    }

    /**
     * 组装两个时间段间的所有月份，返回一个List
     * wangquan add 20120305
     */
    public static List<String> getGAPMonth(String beginDate, String endDate) {

        if (null == beginDate || null == endDate) {
            return new ArrayList<String>();
        }

        List<String> tableList = new ArrayList<String>();

        Set<String> tableSet = new TreeSet<String>();

        Date begin = DateTools.paraseDate(DateTools.yyyy_MM_dd, beginDate);
        Date end = DateTools.paraseDate(DateTools.yyyy_MM_dd, endDate);
        Date lastEnd = DateTools.getLastDayOfMonth(end);
        Date tmpDate = begin;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(tmpDate);
        while (tmpDate.before(lastEnd)) {
            String strDate = DateTools.getDate(calendar.getTime(),
                    DateTools.yyyy_MM_dd);
            strDate = strDate.substring(0, 7).replaceAll("-", "");
            tableSet.add(strDate);
            calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
            tmpDate = calendar.getTime();
        }
        tableList.addAll(tableSet);
        return tableList;

    }


}